/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 
/****************************************************************************
 * 
 * FILENAME
 *     NUC900_VPOST_AUO_A025DL02.c
 *
 * VERSION
 *     0.1 
 *
 * DESCRIPTION
 *
 *
 *
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *
 *
 *     
 * HISTORY
 *     2007.03.15		Created by Shih-Jen Lu
 *
 *
 * REMARK
 *     None
 *
 *
 **************************************************************************/
#include "wblib.h"
#include "NUC900_VPOST_Regs.h"
#include "NUC900_VPOST.h"
#ifdef	HAVE_AUO_A025DL02



#ifdef ECOS
cyg_handle_t	vpost_int_handle;
cyg_interrupt	vpost_int_holder;
#endif

static VPOST_T	_tAUO_A025DL02;

static void Delay(int nCnt)
{
	volatile int  loop;
	for (loop=0; loop<nCnt; loop++);
}

#if 0
static VOID vpostDisp_F_ISR(void)
{
    outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_DISP_F_STATUS);
    vpostVAStartTrigger();
}
static VOID vpostUNDERRUN_ISR(void)
{
	outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_UNDERRUN_INT);
}

static VOID vpostBUS_ERROR_ISR(void)
{
	outpw(REG_LCM_INT_CS,inpw(REG_LCM_INT_CS) | VPOSTB_BUS_ERROR_INT);
}
#ifdef ECOS
static cyg_uint32 vpostIntHandler(cyg_vector_t vector, cyg_addrword_t data)
#else
static VOID vpostIntHandler(void)
#endif
{
   /* clear VPOST interrupt state */
   UINT32 uintstatus;
   
   uintstatus = inpw(REG_LCM_INT_CS);
   if (uintstatus & VPOSTB_DISP_F_STATUS)  
      vpostDisp_F_ISR();
   else if (uintstatus & VPOSTB_UNDERRUN_INT)
      vpostUNDERRUN_ISR();
   else if (uintstatus & VPOSTB_BUS_ERROR_INT)
      vpostBUS_ERROR_ISR();

#ifdef ECOS
	return CYG_ISR_HANDLED;
#endif
}

static void vpostEnable_Int(void)
{
#ifdef ECOS
    cyg_interrupt_create(IRQ_LCD, 1, 0, vpostIntHandler, NULL, &_tAUO_A025DL02.vpost_int_handle, &_tAUO_A025DL02.vpost_int_holder);
    cyg_interrupt_attach(vpost_int_handle);
    cyg_interrupt_unmask(IRQ_LCD);
#else
    sysInstallISR(IRQ_LEVEL_1, IRQ_LCD, (PVOID)vpostIntHandler);
    /* enable VPOST interrupt */
    sysEnableInterrupt(IRQ_LCD);
#endif
    writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | VPOSTB_DISP_INT_EN);
    writew(REG_LCM_INT_CS,readw(REG_LCM_INT_CS) | VPOSTB_UNDERRUN_EN | VPOSTB_DISP_F_EN);
}
#endif


INT vpostOSDInit_AUO_A025DL02(UINT16 ucOSDSrcType,UINT16 usxstart,UINT16 usystart,
											UINT16 usxend,UINT16 usyend,UINT16 usOSDPicWidth)
{

    vpostSetOSDSrc(ucOSDSrcType);
    
    vpostSetOSDBuffer();
    /*if (ucOSDSrcType != 0)
     	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | ucOSDSrcType);
     else
     	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) & 0xffff0fff);//clear OSD SRC setting	
	*/
	vpostOSDSetWindow(usxstart,usystart,usxend,usyend);
     
	writew(REG_LCM_OSD_FBCTRL,0);//clear OSD STRIDE,FF setting
    if ((ucOSDSrcType==OSD_SRC_RGB888)||(ucOSDSrcType==OSD_SRC_RGB666))
    {
		writew(REG_LCM_OSD_FBCTRL,(usOSDPicWidth<<16) | usOSDPicWidth); //OSDFF~OSD_STRIDE
    }
    else if (ucOSDSrcType==OSD_SRC_RGB332)
    {
    	writew(REG_LCM_OSD_FBCTRL,((usOSDPicWidth/4)<<16) | (usOSDPicWidth/4)); //OSDFF~OSD_STRIDE
    }
    else{
        writew(REG_LCM_OSD_FBCTRL,((usOSDPicWidth/2)<<16) | (usOSDPicWidth/2)); //OSDFF~OSD_STRIDE
    }
    //vpostOSDScalingCtrl(1,0,OSD_VUP_1X);
    
    return 0;
}








static VOID vpostSetCRTC_AUO_A025DL02(UINT16 usHorizontal,UINT16 usVertical,UINT16 usVASrcType,UINT16 usPicWidth)
{   
	
#ifdef _AUO_UPS051_MODE
	writew(REG_LCM_CRTC_SIZE,0x01100208); //CRTC_SIZE
	writew(REG_LCM_CRTC_DEND,0x00F00140);           //CRTC_DEND
	writew(REG_LCM_CRTC_HR,0x0154014A); //CRTC_HR
	writew(REG_LCM_CRTC_HSYNC,0x01C001BF); //CRTC_HSYNC
	writew(REG_LCM_CRTC_VR,0x010000Fb); //CRTC_VR
#endif

#ifdef _AUO_UPS052_MODE
#ifdef _AUO_NTSC_MODE
	writew(REG_LCM_CRTC_SIZE,(((usVertical + 32) << 16) | usHorizontal) + 70);      //CRTC_SIZE
	writew(REG_LCM_CRTC_DEND,((usVertical) << 16) | (usHorizontal) );               //CRTC_DEND
	writew(REG_LCM_CRTC_HR,((usHorizontal + 30) << 16) | (usHorizontal + 20));      //CRTC_HR
    writew(REG_LCM_CRTC_HSYNC,((usHorizontal + 12) << 16) | (usHorizontal + 11));   //CRTC_HSYNC
	writew(REG_LCM_CRTC_VR,((usVertical + 11) << 16) | (usVertical + 10));          //CRTC_VR
#else
	writew(REG_LCM_CRTC_SIZE,0x013F0188);      //CRTC_SIZE
	writew(REG_LCM_CRTC_DEND,0x01200140);               //CRTC_DEND
	writew(REG_LCM_CRTC_HR,0x015E0154);      //CRTC_HR
    writew(REG_LCM_CRTC_HSYNC,0x014E014D);   //CRTC_HSYNC
	writew(REG_LCM_CRTC_VR,0x01310125);          //CRTC_VR
		
#endif	
#endif

#ifdef _AUO_CCIR656_MODE
    #ifdef _AUO_NTSC_MODE
    	writew(REG_LCM_CRTC_SIZE,(262 << 16) | 858);       //CRTC_SIZE
    	writew(REG_LCM_CRTC_DEND,(243 << 16) | 720);       //CRTC_DEND
    	writew(REG_LCM_CRTC_HR,(740 << 16) | 730);         //CRTC_HR
        writew(REG_LCM_CRTC_HSYNC,(750 << 16) | 848);      //CRTC_HSYNC
    	writew(REG_LCM_CRTC_VR,(250 << 16) | 246);         //CRTC_VR
    #else
    	writew(REG_LCM_CRTC_SIZE,(312 << 16) | 864);       //CRTC_SIZE
    	writew(REG_LCM_CRTC_DEND,(288 << 16) | 720);       //CRTC_DEND
    	writew(REG_LCM_CRTC_HR,(740 << 16) | 730);         //CRTC_HR
        writew(REG_LCM_CRTC_HSYNC,(800 << 16) | 790);      //CRTC_HSYNC
    	writew(REG_LCM_CRTC_VR,(300 << 16) | 290);         //CRTC_VR
    #endif
#endif

	
    if ((usVASrcType==VA_SRC_RGB888)||(usVASrcType==VA_SRC_RGB666))
    {
		//writew(REG_LCM_VA_FBCTRL,(usPicWidth << 16) | usPicWidth); //VAFF~VA_STRIDE (origin)
		writew(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | (usPicWidth << 16) | usPicWidth); //VAFF~VA_STRIDE (for test)
	}
	else
    {
		//writew(REG_LCM_VA_FBCTRL,((usPicWidth/2) << 16) | (usPicWidth/2)); //VAFF~VA_STRIDE (origin)
		writew(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | ((usPicWidth/2) << 16) | (usPicWidth/2)); //VAFF~VA_STRIDE (for test)
    }
	    

}
static void vpost_A025DL02_RegSetting(UINT8 ucRegIndex, UINT8 ucRegData)
{
    UINT16 usTransmitData;
    
    usTransmitData = (UINT16)(ucRegIndex << 8)|ucRegData ;
    while(inpw(REG_USI_CNTRL) & 0x01);                  // wait MicroWire interface is ready
    outpw(REG_USI_Tx0, usTransmitData);
    outpw(REG_USI_CNTRL, inpw(REG_USI_CNTRL) | 0x01);   // enable MW transfer
    while(inpw(REG_USI_CNTRL) & 0x01);                  // wait MicroWire interface is ready
}
void vpostSetup_AUO_A025DL02(void)
{

    /* initial X900 MicroWire */
    outpw(REG_USI_CNTRL, 0x00000086);       // 16-bit data per transmit, clock rising-edge latch data (falling change)
    outpw(REG_USI_DIVIDER, 49);             // Fsclk = Fpclk/(divider+1)*2. divided by 50
    outpw(REG_USI_SSR, 0x9);               // b4=1: automatic slave select; b3=0: select signal is active LOW
                                            // b0=1: SS0 enabled
   

	/* output-disable,video disable */
	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS)& ~(VPOSTB_DISP_OUT_EN | VPOSTB_VA_EN));
	writew(REG_LCM_DCCS,readw(REG_LCM_DCCS) | VPOSTB_DISP_OUT_EN); //display_out-enable
	Delay(4000);
//	vpostDelay10ms(100);


#ifdef _AUO_UPS051_MODE

	//for(cnt_10=0;cnt_10<10;cnt_10++){
	vpost_A025DL02_RegSetting(5, 0x16);
	Delay(0x100);
	vpost_A025DL02_RegSetting(4, 0x0b);     // set UPS051 input mode	    
	
	Delay(0x100);
	//vpost_A025DL02_RegSetting(7, 0xf1);	    // HBLK setting
//	vpost_A025DL02_RegSetting(7, 0xf2);	    // HBLK setting
//	vpost_A025DL02_RegSetting(7, 0xf5);	    // HBLK setting
	vpost_A025DL02_RegSetting(3, 0x2e);	    // set brightness
	Delay(0x100);
	//vpost_A025DL02_RegSetting(8, 0xc0);	    // set backlight driving capability
	vpost_A025DL02_RegSetting(13, 0x4b);	// set contrast
	Delay(0x100);
	vpost_A025DL02_RegSetting(5, 0x5f);	    // relase standby mode
	Delay(0x100);
	//vpost_A025DL02_RegSetting(5, 0xdf);	    // relase standby mode
	//vpost_A025DL02_RegSetting(3, 0x00);	    // brightness control
	Delay(0x100);
	//vpost_A025DL02_RegSetting(3, 0xff);	    // brightness control
	//vpost_A025DL02_RegSetting(3, 0x40);	    // brightness control
//	vpost_A025DL02_RegSetting(6, 0x14);	    // VBLK setting (20 lines)
//	vpost_A025DL02_RegSetting(12, 0x27);	// polarity
	//vpost_A025DL02_RegSetting(1, 0x58);	    // Flicker pattern output
	//}
#endif	

#ifdef _AUO_CCIR656_MODE
	
	/* AUO UPS052 Power ON setting for CCIR656 */
	vpost_A025DL02_RegSetting(5, 0x16);
	Delay(0x100);
	vpost_A025DL02_RegSetting(4, 0x7b);     // set CCIR656 input mode	    
//	vpost_A025DL02_RegSetting(4, 0x77);     // set CCIR656 input mode	    
	Delay(0x100);
//	vpost_A025DL02_RegSetting(6, 0x16);	    // VBLK setting
	Delay(0x100);
//	vpost_A025DL02_RegSetting(6, 0x04);	    // VBLK setting
	vpost_A025DL02_RegSetting(3, 0x2e);	    // set brightness
	//vpost_A025DL02_RegSetting(3, 0x40);	    // set brightness
	Delay(0x100);
	vpost_A025DL02_RegSetting(13, 0x4b);	// set contrast
	Delay(0x100);
//	vpost_A025DL02_RegSetting(8, 0xc0);	    // set backlight driving capability
	vpost_A025DL02_RegSetting(5, 0x5f);	    // relase standby mode
	Delay(0x100);
	//vpost_A025DL02_RegSetting(1, 0x58);	    // Flicker pattern output	
#endif	

#ifdef _AUO_UPS052_MODE
    #ifdef _AUO_NTSC_MODE	
    	/* AUO UPS052 Power ON setting for 320x240 RGB888 */
    	vpost_A025DL02_RegSetting(5, 0x16);
    	Delay(0x100);
    	vpost_A025DL02_RegSetting(4, 0x17);     // set 320x240, NTSC input mode	    
    	Delay(0x100);
    //	vpost_A025DL02_RegSetting(7, 0xf3);	    // HBLK setting		
    //	vpost_A025DL02_RegSetting(6, 0x16);	    // VBLK setting
    	vpost_A025DL02_RegSetting(3, 0x2e);	    // set brightness
    	Delay(0x100);
    	vpost_A025DL02_RegSetting(13, 0x4b);	// set contrast
    	Delay(0x100);
    //	vpost_A025DL02_RegSetting(8, 0xc0);	    // set backlight driving capability
    	vpost_A025DL02_RegSetting(5, 0x5f);	    // relase standby mode
    	Delay(0x100);
    	//vpost_A025DL02_RegSetting(1, 0x58);	    // Flicker pattern output
    	
    #else
    	/* AUO UPS052 Power ON setting for 320x240 RGB888 */
    	vpost_A025DL02_RegSetting(5, 0x16);
    	vpost_A025DL02_RegSetting(4, 0x13);     // set 320x240, PAL input mode	    
    //	vpost_A025DL02_RegSetting(7, 0xf3);	    // HBLK setting		
    //	vpost_A025DL02_RegSetting(6, 0x16);	    // VBLK setting
    	vpost_A025DL02_RegSetting(3, 0x2e);	    // set brightness
    	vpost_A025DL02_RegSetting(13, 0x4b);	// set contrast
    //	vpost_A025DL02_RegSetting(8, 0xc0);	    // set backlight driving capability
    	vpost_A025DL02_RegSetting(5, 0x5f);	    // relase standby mode
//    	vpost_A025DL02_RegSetting(1, 0x58);	    // Flicker pattern output
    #endif
#endif	
}
void vpostPowerOff_AUO_A025DL02(void)
{
	/* initial X900 MicroWire */
    outpw(REG_USI_CNTRL, 0x00000086);       // 16-bit data per transmit, clock rising-edge latch data (falling change)
    outpw(REG_USI_DIVIDER, 49);             // Fsclk = Fpclk/(divider+1)*2. divided by 50
    outpw(REG_USI_SSR, 0x9);               // b4=1: automatic slave select; b3=0: select signal is active LOW
                                            // b0=1: SS0 enabled
	
	vpost_A025DL02_RegSetting(5, 0x5e);
}


INT vpostLCMInit_AUO_A025DL02(VA_CB_FUNC_T *fnCallBack,UINT16 usVASrcType,UINT8 ucVADisMode,UINT16 usPicWidth,UINT8 ucROT90)
{
	UINT32 VA_FF;
	UINT32 VA_Sride;
	
	_tAUO_A025DL02.usDevWidth = 320;
	_tAUO_A025DL02.usDevHeight = 240;
	_tAUO_A025DL02.uCmdLow = 0;
	_tAUO_A025DL02.ucCmd16t18 = 0;
	_tAUO_A025DL02.uCmdBusWidth = 0;
	_tAUO_A025DL02.uDataBusWidth = VPOSTB_DATA8or9;
	_tAUO_A025DL02.ucMPU_Mode = 0;
#ifndef _AUO_CCIR656_MODE	
	_tAUO_A025DL02.uMPU_ColorMode = VPOSTB_COLORTYPE_16M;
#else
	_tAUO_A025DL02.uMPU_ColorMode = VPOSTB_COLORTYPE_4K;
#endif	
	
	
#ifdef _AUO_CCIR656_MODE
	_tAUO_A025DL02.ucDeviceType = VPOSTB_DEVICE_SYNC_YUV422;

#endif

#ifdef _AUO_UPS051_MODE
    	_tAUO_A025DL02.ucDeviceType = VPOSTB_DEVICE_SYNC_UNIPAC;
#endif    

#ifdef _AUO_UPS052_MODE
    	_tAUO_A025DL02.ucDeviceType = VPOSTB_DEVICE_SYNC_HIGHCOLOR;
#endif


	_tAUO_A025DL02.fnDisplayCallBack = fnCallBack;
	
#if 1
//	if (!_bPWUP)
	{
		//_bPWUP = TRUE;
		vpostSetup_AUO_A025DL02();
		
	}
#endif	
	/* set the display buffer (fetch from VA_BADDR0, if at single buffer mode)*/
	if (vpostSetVABuffer()<0)
		return ERR_NULL_BUF;
	
	/* set display mode */
	vpostSetDisplayMode(ucVADisMode);
	
	/* set display video source format */
	vpostSetVASrc(usVASrcType);
	/*
	if (ucVASrcType!=0)
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | ucVASrcType);
	else
		outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~(7<<8));
	*/
	//18-bit,256k,80mode,mpu-based,cmd18-16L0
	
	
	//vpostSetDeviceCtrl(_tAUO_A025DL02);
	//outpw(REG_LCM_DEV_CTRL,0xA1C00004);
	//outpw(REG_LCM_DEV_CTRL,0x02E0000A);
	
	outpw(REG_LCM_DEV_CTRL,0x0);//set default value
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | _tAUO_A025DL02.uCmdLow 
												   | _tAUO_A025DL02.ucCmd16t18
												   | _tAUO_A025DL02.uCmdBusWidth
												   | _tAUO_A025DL02.uDataBusWidth
												   | _tAUO_A025DL02.ucMPU_Mode
												   | _tAUO_A025DL02.uMPU_ColorMode
												   | _tAUO_A025DL02.ucDeviceType );
	
#ifdef _AUO_UPS051_MODE	
	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x02);      // pixel control for RGB sample order is RGB,RGB....3 cycle per pixel
#endif	                                                        // for SYNC_UNIPAC mode 

#ifdef _AUO_UPS052_MODE	
	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x04);      // pixel control for RGB sample order is RGBxRGBxRGBx...
	                                                            // for SYNC_HIGHCOLOR mode
//	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x010);     // Hsync left shift 2 DCLK
//	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x008);     // Hsync left shift 1 DCLK
#endif	    

#ifdef _AUO_CCIR656_MODE
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | VPOSTB_YUV2CCIR);  // CCIR601 YCbCr format  
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | VPOSTB_VR_LACE);   // Sync interlace
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | VPOSTB_LACE);   // Data Output interlace
	writew(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | VPOSTB_ITUEN);   		 // CCIR656 header encode
#ifdef _AUO_NTSC_MODE
   	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x08);      // NTSC mode test
#else
   	outpw(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | 0x10);      // PAL mode test
#endif
#endif	
	writew(REG_LCM_DEV_CTRL,inpw(REG_LCM_DEV_CTRL) | VPOSTB_FAL_D);     // DCLK rising latch out data
	
	//vpostSetCRTC_AUO_A025DL02(_tAUO_A025DL02.usDevWidth,_tAUO_A025DL02.usDevHeight,
	//					ucVASrcType,usPicWidth);
	
	if (ucROT90)
		vpostSetCRTC_AUO_A025DL02(_tAUO_A025DL02.usDevHeight, _tAUO_A025DL02.usDevWidth,
						usVASrcType,usPicWidth);//
	else
		vpostSetCRTC_AUO_A025DL02(_tAUO_A025DL02.usDevWidth,_tAUO_A025DL02.usDevHeight,
						usVASrcType,usPicWidth);
						
	
	
	/* set video stream frame buffer control */
	VA_FF = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    VA_Sride = (plcdformatex->nScreenWidth)*(nBytesPixel)/4;//word unit
    outpw(REG_LCM_VA_FBCTRL,inpw(REG_LCM_VA_FBCTRL) &~0x7ff07ff | (VA_FF<<16) | VA_Sride);
    
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) | VPOSTB_ENG_RST);
	Delay(100);
	outpw(REG_LCM_DCCS,inpw(REG_LCM_DCCS) & ~VPOSTB_ENG_RST);
	Delay(100);
	
	//vpostVAStartTrigger();
	//vpostSetup_AUO_A025DL02();					
	//vpostEnable_Int();
	return 0;
}



#endif	/* HAVE_SAMSUNG_80_18IT */